package com.hue.gulimail.gulimailauth.web;

import com.hue.common.constant.AuthConstant;
import com.hue.common.to.CheckCodeTo;
import com.hue.common.utils.Error;
import com.hue.common.utils.R;
import com.hue.gulimail.gulimailauth.feign.MemberFeignService;
import com.hue.gulimail.gulimailauth.feign.ThireFeignService;
import com.hue.gulimail.gulimailauth.vo.RegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.thymeleaf.util.StringUtils;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: 姚凤桥
 * @Date: 2021/11/23 21:36
 * @Description:
 */
@Controller
public class RegisterController {
    @Autowired
    private ThireFeignService thireFeignService;
    @Autowired
    private MemberFeignService memberFeignService;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @ResponseBody
    @GetMapping("/email/sendEmail/{target}")
    public R sendEmail(@PathVariable("target") String target) {
        String redisCode = redisTemplate.opsForValue().get(AuthConstant.EMAIL_CODE_PREFIX + target);

        if (StringUtils.isEmpty(redisCode)) {
            sendEmail0(target);
            return R.ok();
        }

        long time = Long.parseLong(redisCode.split("_")[1]);
        if (System.currentTimeMillis() - time > 60 * 1000) {
            //重新发送验证码
            sendEmail0(target);
            return R.ok();
        }

        return R.error(Error.EMAIL_ERROR.getCode(), Error.EMAIL_ERROR.getMsg());
    }

    private void sendEmail0(String target) {
        //产生6位随机验证码
        String code = UUID.randomUUID().toString().substring(0, 6);
        CompletableFuture.runAsync(() -> {
            //将验证码存储到redis中
            redisTemplate.opsForValue().set(AuthConstant.EMAIL_CODE_PREFIX + target,
                    code + "_" + System.currentTimeMillis(), 15, TimeUnit.MINUTES);
            //发送邮件
            CheckCodeTo checkCodeTo = new CheckCodeTo();
            checkCodeTo.setTarget(target);
            checkCodeTo.setTitle("谷粒商城验证码邮件");
            checkCodeTo.setText("验证码:" + code + ",15分钟内有效!");
            thireFeignService.sendEmail(checkCodeTo);
        }, threadPoolExecutor);
    }

    /**
     * TODO redirectAttributes.addFlashAttribute()在重定向中设置数据时是将数据存储到session中，条到下一个页面后从session中取出数据
     * ，并且删除session中的数据，此时就必须考虑分布式下的session问题
     *
     * @param registerVo
     * @param result
     * @param redirectAttributes
     * @return
     */
    @PostMapping("/register")
    public String register(@Valid RegisterVo registerVo, BindingResult result, RedirectAttributes redirectAttributes) {
        if (result.hasErrors()) {
            //数据效验出错
            Map<String, String> errorMap = result.getFieldErrors().stream()
                    .collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("error", errorMap);
            //跳转到注册页面
            return "redirect:http://auth.gulimail.com/register.html";
        }

        //判断验证码是否正确
        String redisCode = redisTemplate.opsForValue().get(AuthConstant.EMAIL_CODE_PREFIX + registerVo.getEmail());
        if (StringUtils.isEmpty(redisCode) || !redisCode.split("_")[0].equals(registerVo.getCode())) {
            Map<String, String> errorMap = new HashMap<>();
            errorMap.put("code", "验证码不正确");
            redirectAttributes.addFlashAttribute("error", errorMap);
            return "redirect:http://auth.gulimail.com/register.html";
        }

        //验证码通过，删除redis缓存的验证码
        redisTemplate.delete(AuthConstant.EMAIL_CODE_PREFIX + registerVo.getEmail());
        // 调用远程服务发起注册
        R r = memberFeignService.register(registerVo);

        //注册成功,跳转到登录页面
        if ((Integer) r.get("code") == 0) {
            return "redirect:http://auth.gulimail.com/login.html";
        }

        //注册失败
        Map<String, String> errorMap = new HashMap<>();
        if ((Integer) r.get("code") == Error.USERNAME_EXIST_ERROR.getCode()) {
            errorMap.put("username", (String) r.get("msg"));
        }else if((Integer) r.get("code") == Error.EMAIL_EXIST_ERROR.getCode()){
            errorMap.put("email", (String) r.get("msg"));
        }
        redirectAttributes.addFlashAttribute("error", errorMap);

        return "redirect:http://auth.gulimail.com/register.html";
    }
}
